package org.erp.store.strategy.impl;

import lombok.extern.slf4j.Slf4j;
import org.erp.common.enums.DeviceInventoryEvent;
import org.erp.store.domain.entity.DeviceInventory;
import org.erp.store.domain.dto.BatchDeviceInventoryDto;
import org.erp.store.domain.dto.BatchDeviceInventoryResponseDto;
import org.erp.store.infrastructure.enums.DeviceInventoryState;
import org.erp.store.infrastructure.event.InventoryLogEvent;
import org.erp.store.service.DeviceInventoryService;
import org.erp.store.strategy.InventoryEventStrategy;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
 * 入库处理策略
 */
@Slf4j
@Component
public class StorageInventoryEventStrategy extends BaseInventoryEventStrategy implements InventoryEventStrategy {
    @Resource
    private DeviceInventoryService deviceInventoryService;

    @Resource
    private ApplicationEventPublisher eventPublisher;

    @Override
    public DeviceInventoryEvent getEvent() { return DeviceInventoryEvent.STORAGE; }

    @Override
    public BatchDeviceInventoryResponseDto execute(BatchDeviceInventoryDto dto) {
        Assert.isTrue(dto.getDeviceList() != null && !dto.getDeviceList().isEmpty(), "库存列表不能为空");
        log.info(" Storage Started ,数量{}", dto.getDeviceList().size());
        List<String> codes = dto.getDeviceList().stream().map(DeviceInventory::getProductCode).filter(Objects::nonNull).collect(Collectors.toList());
        long startTime1 = System.currentTimeMillis();
        List<String> exists = codes.isEmpty() ? Collections.emptyList() : deviceInventoryService.selectExistingCodes(codes);
        long endTime1 = System.currentTimeMillis();
        log.info("查询已存在库存耗时: {} ms", endTime1 - startTime1);
        Set<String> existSet = new HashSet<>(exists);
        List<DeviceInventory> inventoryList = dto.getDeviceList();
        List<DeviceInventory> toInsert = new ArrayList<>();
        Map<String, Integer> originalStateMap = new HashMap<>(inventoryList.size() * 2);
        for (DeviceInventory inv : inventoryList) {
            if (inv.getProductCode() == null || existSet.contains(inv.getProductCode())) { continue; }
            inv.setOperateId(dto.getOperateId());
            inv.setOperateName(dto.getOperateName());
            inv.setStatus(DeviceInventoryState.INBOUND.getCode());
            inv.setLastInboundTime(new Date());
            toInsert.add(inv);
            originalStateMap.put(inv.getProductCode(), DeviceInventoryState.INBOUND.getCode());
        }
        int count=0;
        if (!toInsert.isEmpty()) {
            long startTime2 = System.currentTimeMillis();
            count = deviceInventoryService.saveBatch(toInsert) ? toInsert.size() : 0;
            long endTime2 = System.currentTimeMillis();
            log.info("入库库存耗时: {} ms", endTime2 - startTime2);
            if(count > 0){
                eventPublisher.publishEvent(new InventoryLogEvent(toInsert, dto.getTargetEvent(),originalStateMap));
            }

        }
        BatchDeviceInventoryResponseDto response = new BatchDeviceInventoryResponseDto();
        response.setTotalCount(dto.getDeviceList().size());
        response.setSuccessCount(count);
        response.setFailedCount(response.getTotalCount() - response.getSuccessCount());
        response.setTargetEvent(DeviceInventoryEvent.STORAGE);
        return response;
    }


}
